package com.zxmr.hospital.customer.action;

import java.util.ArrayList;
import java.util.List;

import com.alibaba.fastjson.JSON;
import com.zxmr.action.Request;
import com.zxmr.action.Response;
import com.zxmr.action.ResponsePayload;
import com.zxmr.action.ResultCode;
import com.zxmr.domain.Comment;
import com.zxmr.domain.Opportunity;
import com.zxmr.domain.account.AccountType;
import com.zxmr.domain.account.User;
import com.zxmr.domain.service.OpportunityService;
import com.zxmr.domain.service.UserService;
import com.zxmr.hospital.customer.dto.CommentsDTO;
import com.zxmr.navigate.ExecuteException;
import com.zxmr.navigate.Executor;
import com.zxmr.util.ResourceManager;
import com.zxmr.util.UserTraceManager;
import com.zxmr.util.Utils;

public class OpportunityComment extends Executor{

	enum method{
		add,
		queryall,
		delete,
		update;
	}
	@Override
	public void execute(Request request, Response response) {
		// TODO Auto-generated method stub
		method method = Enum.valueOf(method.class, this.getElement().getMethod());
		
		try
		{
			switch(method)
			{
			case add:
				add(request,response);
				break;
			case update:
				update(request,response);
				break;
			case delete:
				delete(request,response);
				break;
			case queryall:
				queryAll(request,response);
				break;
			}
		}catch(Exception e)
		{
			ResponsePayload payload = new ResponsePayload();
			if(e instanceof ExecuteException)
			{
				payload.setValue(e.getMessage());
			}else
			{
				e.printStackTrace();
				payload.setValue("internal error");
			}
			response.setPayload(payload);
			response.setResult(ResultCode.COMPONENT_ERROR);
		}
	}

	private void add(Request request,Response response)throws ExecuteException
	{
		OpportunityService service = new OpportunityService();
		
		long opportunityId = getOpportunityID(request);
		Opportunity opportunity = service.queryOpportunity(opportunityId);
		authAccountToOpportunity(request.getAccount(),opportunity);
		
		if(request.getAccount().getAccountType()!=AccountType.Supervisor &&
				!opportunity.getOwner().equals(request.getAccount().getName())
				&& !this.isAuthorized(request.getAccount().getId(), "commentToOpportunityOthers"))
		{
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.noauth.commentToOpportunityOthers"));
		}
		Comment comment = parseComment(request);
		
		boolean result = service.addComment(comment, opportunityId);
		
		if(result)
		{
			CommentsDTO dto = convertCommentToDTO(comment);
			ResponsePayload payload = new ResponsePayload(JSON.toJSONString(dto));
			response.setPayload(payload);
			
			String action = ResourceManager.getInstance().getMessage("com.zxmr.customer.addOpportunityComment",
						String.valueOf(opportunity.getId()),String.valueOf(comment.getId()));
			UserTraceManager.addTrace(action, request.getAccount());
		}else
		{
			response.setPayload(new ResponsePayload("internal error"));
			response.setResult(ResultCode.COMPONENT_ERROR);
		}
	}
	private Comment parseComment(Request request)throws ExecuteException
	{
		Comment comment = new Comment();
		comment.setContent(request.getRequestParameters().get("comment"));
		comment.setUser(request.getAccount().getId());
		
		comment.setTime(Utils.getCurrentTime());
		
		return comment;
	}
	private void delete(Request request,Response response)throws ExecuteException
	{
		if(request.getAccount().getAccountType() != AccountType.Supervisor
				&& !this.isAuthorized(request.getAccount().getId(), "deleteOpportunityComment"))
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.noauth.deleteOpportunityComment"));
		
		int commentID = getCommentID(request);
		OpportunityService service = new OpportunityService();
		
		Comment comment = service.queryComment(commentID);
		
		if(comment.getUser() == request.getAccount().getId() 
				|| request.getAccount().getAccountType() == AccountType.Supervisor)
		{
			if(!service.deleteComment(comment.getId()))
			{
				response.setResult(ResultCode.COMPONENT_ERROR);
				response.setPayload(new ResponsePayload("internal error"));
			}else
			{
				String action = ResourceManager.getInstance().getMessage("com.zxmr.customer.deleteOpportunityComment",
						String.valueOf(comment.getId()));
				UserTraceManager.addTrace(action, request.getAccount());
			}
		}else
		{
			response.setPayload(new ResponsePayload(ResourceManager.getInstance().getMessage("com.zxmr.customer.noauth.deleteOtherOpportunityComment")));
			response.setResult(ResultCode.COMPONENT_ERROR);
		}
	}
	private void update(Request request,Response response)throws ExecuteException
	{
		
	}
	private void queryAll(Request request,Response response)throws ExecuteException
	{
		long opportunityId = getOpportunityID(request);
		OpportunityService service = new OpportunityService();
		Opportunity opportunity = service.queryOpportunity(opportunityId);
		
		authAccountToOpportunity(request.getAccount(),opportunity);
		
		if(request.getAccount().getAccountType()!=AccountType.Supervisor
				&& !opportunity.getOwner().equals(request.getAccount().getName())
				&& !this.isAuthorized(request.getAccount().getId(), "queryOpportunityOthers"))
		{
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.noauth.queryOpportunityOthers"));
		}
		
		List<Comment> comments = service.queryAllComments(opportunityId);
		List<CommentsDTO> dtos = convertCommentsToDTO(comments);
		
		ResponsePayload payload = new ResponsePayload(JSON.toJSONString(dtos));
		response.setPayload(payload);
	}
	private List<CommentsDTO> convertCommentsToDTO(List<Comment> comments)
	{
		if(comments == null)return null;
		List<CommentsDTO> dtos = new ArrayList<CommentsDTO>();
		for(Comment comment : comments)
		{

			CommentsDTO dto = convertCommentToDTO(comment);
			dtos.add(dto);
		}
		
		return dtos;
	}
	private CommentsDTO convertCommentToDTO(Comment comment)
	{
		CommentsDTO dto = new CommentsDTO();
		dto.setId(comment.getId());
		dto.setContent(comment.getContent());
		dto.setTime(comment.getTime());
		UserService service = new UserService();
		dto.setUser(service.getUserName(comment.getUser()));
		return dto;
	}
	private void authAccountToOpportunity(User user,Opportunity opp)throws ExecuteException
	{
		if(opp == null || user.getCompany() != opp.getCompany())
		{
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.noauth"));
		}
	}
	private long getOpportunityID(Request request)throws ExecuteException
	{
		String opp = request.getRequestParameters().get("opp");
		try
		{
			return Long.parseLong(opp);
		}catch(Exception e)
		{
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.errorPara"));
		}
	}
	private int getCommentID(Request request)throws ExecuteException
	{
		String id = request.getRequestParameters().get("id");
		try
		{
			return Integer.parseInt(id);
		}catch(Exception e)
		{
			throw new ExecuteException(ResourceManager.getInstance().getMessage("com.zxmr.customer.errorPara"));
		}
	}
}